<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>bosdyn.client.image_service_helpers &mdash; Spot 5.0.1.1 documentation</title>
      <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
      <link rel="stylesheet" href="../../../_static/style.css" type="text/css" />
    <link rel="shortcut icon" href="../../../_static/bd-favicon.png"/>
    <link rel="canonical" href="https://dev.bostondynamics.com/_modules/bosdyn/client/image_service_helpers.html" />
  <!--[if lt IE 9]>
    <script src="../../../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
        <script src="../../../_static/jquery.js"></script>
        <script src="../../../_static/_sphinx_javascript_frameworks_compat.js"></script>
        <script data-url_root="../../../" id="documentation_options" src="../../../_static/documentation_options.js"></script>
        <script src="../../../_static/doctools.js"></script>
        <script src="../../../_static/sphinx_highlight.js"></script>
    <script src="../../../_static/js/theme.js"></script>
    <link rel="index" title="Index" href="../../../genindex.html" />
    <link rel="search" title="Search" href="../../../search.html" /> 
</head>

<body class="wy-body-for-nav"> 
  <div class="wy-grid-for-nav">
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >

          
          
          <a href="../../../README.html">
            
              <img src="../../../_static/bd-official-white.png" class="logo" alt="Logo"/>
          </a>
              <div class="version">
                5.0.1.1
              </div>
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" aria-label="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>
        </div><div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="Navigation menu">
              <ul>
<li class="toctree-l1"><a class="reference internal" href="../../../docs/concepts/README.html">Concepts</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/about_spot.html">About Spot</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/orbit/about_orbit.html">About Orbit (formerly Scout)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/orbit/orbit_api.html">Orbit API</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/networking.html">Networking</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/base_services.html">Base services</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/geometry_and_frames.html">Geometry and Frames</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/robot_services.html">Robot services</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/estop_service.html">E-Stop</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/keepalive_service.html">KeepAlive (BETA)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/audio_visual.html">Audio Visual</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/lease_service.html">Lease</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/developing_api_services.html">Developing API Services</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/service_customization.html">Service Customization</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/faults.html">Faults</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/autonomy/README.html">Autonomy services</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/graphnav_tech_summary.html">Autonomy Technical Summary</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/autonomous_navigation_code_examples.html">Autonomous navigation code examples</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/components_of_autonomous_navigation.html">Components of autonomous navigation</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/docking.html">Docking</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/typical_autonomous_navigation_use_case.html">Typical autonomous navigation use case</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/autonomous_navigation_services.html">Autonomous navigation services</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/graphnav_service.html">GraphNav service</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/graphnav_map_structure.html">GraphNav map structure</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/graphnav_area_callbacks.html">GraphNav area callbacks</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/initialization.html">Initialization</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/localization.html">Localization</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/graphnav_and_robot_locomotion.html">GraphNav and robot locomotion</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/missions_service.html">Missions service</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/autowalk_service.html">Autowalk service</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/network_compute_bridge.html">Network compute bridge</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/auto_return.html">AutoReturn service</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/directed_exploration.html">Directed Exploration</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/autonomy/gps.html">GPS</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/choreography/README.html">Choreography</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/choreography/choreography_service.html">Choreography Service</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/choreography/move_reference.html">Move Reference Guide</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/choreography/custom_gait.html">CustomGait Reference</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/choreography/choreographer_setup.html">Choreographer Setup</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/choreography/choreographer.html">Choreographer Overview</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/choreography/robot_controls_in_choreographer.html">Robot Connections in Choreographer</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/choreography/animations_in_choreographer.html">Animations in Choreography</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/choreography/animation_file_specification.html">Animation File Format</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/choreography/choreography_in_tablet.html">Tablet Choreography Mode</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/choreography/choreography_in_autowalk.html">Choreography Actions in Autowalk</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/joint_control/README.html">Joint Control API</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/joint_control/supplemental_data.html">Supplemental Robot Information</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../docs/concepts/joint_control/knee_torque_limits.html">Knee Torque Limits</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/arm/README.html">Spot Arm</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/arm/arm_specification.html">Arm and Gripper Specification</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/arm/arm_concepts.html">Concepts</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/arm/arm_services.html">Services</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/concepts/data.html">Spot Data</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/data_acquisition_overview.html">Data Acquisition Overview</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/data_acquisition_output.html">Data Acquisition Output</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/writing_services_for_data_acquisition.html">Integrate Payloads with the API</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/data_buffer_overview.html">Data Buffer Overview</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/bddf.html">BDDF File Format</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/concepts/data_acquisition_thermal_raw.html">Thermal Raw Data Format</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../../docs/python/README.html">Python</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/python/quickstart.html">Quickstart</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/python/understanding_spot_programming.html">Understanding Spot Programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../python/examples/README.html">Examples</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../python/examples/docs/basic_service_examples.html">Basic Service Examples</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/hello_spot/README.html">Hello Spot</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/directory/README.html">Directory</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/get_robot_state/README.html">Get Robot State</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/get_robot_state_async/README.html">Get Robot State Async</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/get_image/README.html">Get Image</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/get_world_objects/README.html">Get World Objects</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/get_mission_state/README.html">Get Mission State</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/estop/README.html">E-Stop</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/time_sync/README.html">Time Sync</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/comms_test/README.html">Comms Test</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/disable_ir_emission/README.html">IR Enable/Disable</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/reset_safety_stop/README.html">Reset Safety Stop</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/audio_visual/audio_visual_params/README.html">Audio Visual Params</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/audio_visual/audio_visual_behaviors/README.html">Audio Visual Behaviors</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/examples/docs/robot_behavior_examples.html">Robot Behavior and Commands Examples</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/stance/README.html">Stance</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/frame_trajectory_command/README.html">Frame Trajectory</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/spot_light/README.html">Spot Light</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/upload_choreographed_sequence/README.html">Upload Choreographed Sequence</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/xbox_controller/README.html">Xbox Controller</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/wasd/README.html">WASD</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/docking/README.html">Docking</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/animation_recorder/README.html">Animation Recorder</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/auto_return/README.html">Auto Return</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/fan_command/README.html">Fan Commands</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_wasd/README.html">ARM WASD</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/examples/docs/arm_examples.html">Arm Command Examples</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_simple/README.html">Simple Arm Motion</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_stow_unstow/README.html">Stow/unstow Arm</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_freeze/README.html">Arm Freeze</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_and_mobility_command/README.html">Arm and Mobility Command</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_with_body_follow/README.html">Arm Command with Body Following</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_constrained_manipulation/README.html">Arm Constrained Manipulation</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_trajectory/README.html">Arm Trajectory</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_trajectory/README.html#long-trajectory">Long Trajectory</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_joint_move/README.html">Arm Joint Move Command</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_force_control/README.html">Arm Force Control Command</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_grasp/README.html">Arm Grasp Command</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_grasp_carry_overrides/README.html">Arm Grasp and Carry Overrides</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_gaze/README.html">Arm Gaze Command</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_surface_contact/README.html">Arm Command with Surface Contact</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_door/README.html">Arm Door Opening Command</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_walk_to_object/README.html">Walk to And Pick Up Object</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_gcode/README.html">Writing Gcode</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/gripper_camera_params/README.html">Gripper Camera Parameters</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_impedance_control/README.html">Arm Impedance Control</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/inverse_kinematics/README.html">Inverse Kinematics</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/arm_wasd/README.html">Arm WASD</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/joint_control/README.html">Wiggle Arm</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/examples/docs/payloads_examples.html">Payloads and Registration Examples</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/payloads/README.html">Payloads</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/self_registration/README.html">Self Registration</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/service_faults/README.html">Faults</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/velodyne_client/README.html">Velodyne</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/core_io_gpio/README.html">CORE I/O GPIO</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/metrics_over_coreio/README.html">Overview</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/metrics_over_coreio/README.html#usage">Usage</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/metrics_over_coreio/README.html#components">Components</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/metrics_over_coreio/README.html#recommended-debugging">Recommended debugging</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/extensions/README.html">Extensions</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/examples/docs/perception_world_objects_examples.html">Perception and World Objects Examples</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/get_image/README.html">Get Image</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/get_world_objects/README.html">Get World Objects</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/world_object_with_image_coordinates/README.html">World Object With Image Coordinates</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/world_object_mutations/README.html">World Object Mutations</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/visualizer/README.html">Visualizer</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/gripper_camera_params/README.html">Gripper Camera Parameters</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/spot_cam/README.html">Spot CAM Services</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/spot_cam/README.html#spot-cam-video-core-io-extension-example">Spot Cam Video Core IO Extension Example</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/stitch_front_images/README.html">Stitch Front Images</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/get_depth_plus_visual_image/README.html">Project Depth Data on Visual Images</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/service_customization/custom_parameter_image_server/README.html">Custom Parameter Image Server</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/fiducial_follow/README.html">Fiducial Follow</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/spot_tensorflow_detector/README.html">Tensorflow Detector</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/service_customization/custom_parameter_ncb_worker/README.html">Custom Parameter Tensorflow Detector</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/network_compute_bridge/README.html">Machine Learning with the Network Compute Bridge</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/network_compute_bridge/fire_extinguisher_server/README.html">Fire Extinguisher Detector with the Network Compute Bridge</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/ray_cast/README.html">Ray Cast</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/user_nogo_regions/README.html">No-Go Regions</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/gps_service/README.html">GPS</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/examples/docs/logging_examples.html">Logging Examples</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/bddf_download/README.html">BDDF Download</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/data_buffer/README.html">Data Buffer</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/data_service/README.html">Data Service</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/logging/README.html">Logging</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/log_status/README.html">Log Status</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/examples/docs/data_acquisition_examples.html">Data Acquisition Examples</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/data_acquisition_service/README.html">Data Acquisition Service</a><ul>
<li class="toctree-l5"><a class="reference internal" href="../../../python/examples/data_acquisition_service/signals_coreio_modem_plugin/README.html">Modem Signals</a></li>
</ul>
</li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/service_faults/README.html">Faults</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/service_customization/custom_parameter_image_server/README.html">Custom Parameter Image Service</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/service_customization/custom_parameters_data_acquisition/README.html">Custom Parameter Data Acquisition Plugin</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/get_image/README.html">Test Image Service Implementation with Get Image</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/post_docking_callbacks/README.html">Post Docking Callbacks</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/cloud_upload/README.html">Cloud Upload</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/comms_mapping/README.html">Comms image service</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/comms_mapping/README.html#how-to-use">How to use</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/data_acquisition_service/signals_coreio_modem_plugin/README.html">CoreIO Modem Signals Plugin</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/tester_programs/README.html">Tester Programs</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/examples/docs/autonomy_and_missions_examples.html">Autonomy and Missions Examples</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/graph_nav_anchoring_optimization/README.html">Graph Nav Anchoring Optimization</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/graph_nav_command_line/README.html">GraphNav and Recording Service Command Line Interfaces</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/graph_nav_command_line/README.html#example-programs">Example Programs</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/graph_nav_extract_point_cloud/README.html">Graph Nav Extract Point Cloud</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/graph_nav_view_map/README.html">Graph Nav View Map</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/graph_nav_view_gps/README.html">Graph Nav View GPS Data</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/get_mission_state/README.html">Get Mission State</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/remote_mission_service/README.html">Remote Mission Service</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/mission_question_answerer/README.html">Mission Question Answerer</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/mission_recorder/README.html">Mission Recorder</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/replay_mission/README.html">Replay Mission</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/post_docking_callbacks/README.html">Post Docking Callbacks</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/area_callback/README.html">Area Callbacks</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/edit_autowalk/README.html">Edit Autowalk</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/record_autowalk/README.html">Record Autowalk</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/extract_images_from_walk/README.html">Extract Images from Autowalk</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/network_request_callback/README.html">Network Request Callback</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/network_request_callback/README.html#id1">Network Request Callback</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/remote_mission_service/spot_check/README.html">SpotCheck Mission Service</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/examples/docs/joint_control_examples.html">Joint Control API Examples</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/examples/docs/orbit.html">Orbit</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/orbit/hello_orbit/README.html">Hello Orbit</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/orbit/export_run_archives/README.html">Export Run Archives</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/orbit/export_site_walk_archives/README.html">Export Sitewalk Archives</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/orbit/anomalies/README.html">Anomalies</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/orbit/schedule_mission/README.html">Schedule Mission</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/orbit/runs_response/README.html">Runs Response</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/orbit/send_robot_back_to_dock/README.html">Return to Dock</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/orbit/toggle_mission_based_on_weather/README.html">Mission Toggle</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/orbit/webhook/README.html">Webhook</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/orbit/backups/README.html">Backups</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/orbit/webhook_integration/README.html">Webhook Integrations</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/examples/orbit/webhook_integration/README.html#example-overview">Example Overview</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../../python/README.html">Python Reference Guide</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/README.html">Client</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/area_callback.html">Area Callback</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/area_callback_region_handler_base.html">Area Callback Region Handler</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/area_callback_service_runner.html">Area Callback Service Runner</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/area_callback_service_servicer.html">Area Callback Servicer</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/area_callback_service_utils.html">Area Callback Service Utils</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/arm_surface_contact.html">Arm Surface Contact</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/async_tasks.html">Async Tasks</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/audio_visual.html">Audio Visual</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/audio_visual_helpers.html">Audio Visual Helpers</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/auth.html">Auth</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/auto_return.html">Auto Return</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/autowalk.html">Autowalk</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/bddf.html">BDDF</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/bddf_download.html">BDDF Download</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/channel.html">Channel</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/command_line.html">Command</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/common.html">Common</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/data_acquisition.html">Data Acquisition</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/data_acquisition_helpers.html">Data Acquisition Helpers</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/data_acquisition_plugin.html">Data Acquisition Plugin</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/data_acquisition_plugin_service.html">Data Acquisition Plugin Service</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/data_acquisition_store.html">Data Acquisition Store</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/data_buffer.html">Data Buffer</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/data_chunk.html">Data Chunk</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/data_service.html">Data Service</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/directory_registration.html">Directory Registration</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/directory.html">Directory</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/docking.html">Docking</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/door.html">Door</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/estop.html">E-Stop</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/error_callback_result.html">Error Callback Result</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/exceptions.html">Exceptions</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/fault.html">Fault</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/frame_helpers.html">Frame Helpers</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/graph_nav.html">Graph Nav</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/gripper_camera_param.html">Gripper Camera Params</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/gps/README.html">GPS</a><ul>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/gps/aggregator_client.html">Aggregator Client</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/gps/gps_listener.html">GPS Listener</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/gps/NMEAParser.html">NMEA Parser</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/gps/ntrip_client.html">NTRIP Client</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/gps/registration_client.html">Registration Client</a></li>
</ul>
</li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/image.html">Image</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html">Image Service Helpers</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/inverse_kinematics.html">Inverse Kinematics</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/ir_enable_disable.html">IR Enable/Disable</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/keepalive.html">Keep Alive</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/lease.html">Lease</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/lease_resource_hierarchy.html">Lease Resource Hierarchy</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/lease_validator.html">Lease Validator</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/license.html">License</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/local_grid.html">Local Grid</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/log_status.html">Log Status</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/math_helpers.html">Math Helpers</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/manipulation_api_client.html">Manipulation API</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/map_processing.html">Map Processing</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/metrics_logging.html">Metrics Logging</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/network_compute_bridge_client.html">Network Compute Bridge</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/payload_registration.html">Payload Registration</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/payload_software_update.html">Payload Software Update</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/payload_software_update_initiation.html">Payload Software Update Initiation</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/payload.html">Payload</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/point_cloud.html">Point Cloud</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/power.html">Power</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/processors.html">Processors</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/ray_cast.html">Ray casting</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/recording.html">Recording</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/robot_command.html">Robot Command</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/robot_id.html">Robot ID</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/robot.html">Robot</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/robot_state.html">Robot State</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/sdk.html">SDK</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/server_util.html">Server Util</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/service_customization_helpers.html">Service Customization Helpers</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/signals_helpers.html">Signals Helpers</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/spot_cam/README.html">Spot CAM</a><ul>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/spot_cam/audio.html">Audio</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/spot_cam/compositor.html">Compositor</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/spot_cam/health.html">Health</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/spot_cam/lighting.html">Lighting</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/spot_cam/lights_helper.html">Lights Helper</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/spot_cam/media_log.html">Media Log</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/spot_cam/network.html">Network</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/spot_cam/power.html">Power</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/spot_cam/ptz.html">PTZ</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/spot_cam/streamquality.html">Stream Quality</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/spot_cam/version.html">Version</a></li>
</ul>
</li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/spot_check.html">Spot Check</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/time_sync.html">Time Sync</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/token_cache.html">Token Cache</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/token_manager.html">Token Manager</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/units_helpers.html">Units Helpers</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/util.html">Util</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-client/src/bosdyn/client/world_object.html">World Object</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/README.html">Core</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/README.html">BDDF</a><ul>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/base_data_reader.html">Base Data Reader</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/block_writer.html">Block Writer</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/bosdyn.html">BDDF Conventions</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/common.html">Common</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/data_reader.html">Data Reader</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/data_writer.html">Data Writer</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/file_indexer.html">File Indexer</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/grpc_proto_reader.html">GRPC Proto Reader</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/grpc_reader.html">GRPC Reader</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/grpc_service_reader.html">GRPC Service Reader</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/grpc_service_writer.html">GRPC Service Writer</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/message_reader.html">Message Reader</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/pod_series_reader.html">POD Series Reader</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/pod_series_writer.html">POD Series Writer</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/protobuf_channel_reader.html">Protobuf Channel Reader</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/protobuf_reader.html">Protobuf Reader</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/protobuf_series_writer.html">Protobuf Series Writer</a></li>
<li class="toctree-l5"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/bddf/stream_data_reader.html">Stream Data Reader</a></li>
</ul>
</li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/geometry.html">Geometry</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/util.html">Util</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-core/src/bosdyn/deprecated.html">Deprecated</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/bosdyn-mission/src/bosdyn/mission/README.html">Mission</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-mission/src/bosdyn/mission/client.html">Client</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-mission/src/bosdyn/mission/constants.html">Constants</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-mission/src/bosdyn/mission/exceptions.html">Exceptions</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-mission/src/bosdyn/mission/remote_client.html">Remote Client</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-mission/src/bosdyn/mission/server_util.html">Server Util</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-mission/src/bosdyn/mission/util.html">Util</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/bosdyn-choreography-client/src/bosdyn/choreography/client/README.html">Choreography</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-choreography-client/src/bosdyn/choreography/client/choreography.html">Choreography</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-choreography-client/src/bosdyn/choreography/client/animation_file_to_proto.html">Animation File to Proto</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-choreography-client/src/bosdyn/choreography/client/animation_file_conversion_helpers.html">Animation File to Proto Helpers</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/bosdyn-orbit/src/bosdyn/orbit/README.html">Orbit (formerly Scout)</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-orbit/src/bosdyn/orbit/client.html">Client</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-orbit/src/bosdyn/orbit/utils.html">Utils</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-orbit/src/bosdyn/orbit/exceptions.html">Exceptions</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../../python/bosdyn-scout/src/bosdyn/scout/README.html">Scout (deprecated)</a><ul>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-scout/src/bosdyn/scout/client.html">Client</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-scout/src/bosdyn/scout/utils.html">Utils</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../../python/bosdyn-scout/src/bosdyn/scout/exceptions.html">Exceptions</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/python/fetch_tutorial/fetch1.html">Fetch Tutorial</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/python/fetch_tutorial/fetch2.html">Part 2: Training the Model</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/python/fetch_tutorial/fetch3.html">Part 3: Evaluating the Model</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/python/fetch_tutorial/fetch4.html">Part 4: Autonomous Pick Up</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/python/fetch_tutorial/fetch5.html">Part 5: Detecting People and Playing Fetch</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/python/fetch_tutorial/fetch6.html">Part 6: Running the model on Core IO</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/python/daq_tutorial/daq1.html">Data Collection Tutorial</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/python/daq_tutorial/daq2.html">Part 2: Capturing images</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/python/daq_tutorial/daq3.html">Part 3: Capturing other data</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/python/daq_tutorial/daq4.html">Part 4: Deploying to the CORE I/O</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/python/daq_tutorial/daq5.html">Part 5: Collecting data</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/python/daq_tutorial/daq6.html">Part 6: Processing collected data</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../../docs/payload/README.html">Payloads</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/payload/payload_configuration_requirements.html">Payload configuration requirements</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/payload/mechanical_interfaces.html">Mechanical interfaces</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/payload/robot_mounting_rails.html">Robot mounting rails</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/payload/guidelines_for_robust_payload_design.html">Guidelines for robust payload design</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/payload/robot_electrical_interface.html">Robot electrical interface</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/payload/coreio_documentation.html">CORE I/O Documentation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/payload/coreio_openvpn_extension.html">CORE I/O OpenVPN Extension</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/payload/configuring_payload_software.html">Configuring payload software</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/payload/docker_containers.html">Dockerize payload software</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/payload/spot_core_documentation.html">Pre-3.2 Spot CORE Documentation</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/payload/spot_core_portainer.html">Configuring Docker containers in SpotCORE</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/payload/spot_core_cockpit.html">Spot CORE system management tool: Cockpit</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../../docs/payload/spot_core_vnc.html">Spot CORE VNC</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../../docs/protos/README.html">API Protocol</a><ul>
<li class="toctree-l2"><a class="reference internal" href="../../../docs/protos/style_guide.html">Style Guide</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../../protos/bosdyn/api/README.html">Proto Reference Guide</a><ul>
<li class="toctree-l3"><a class="reference internal" href="../../../protos/bosdyn/api/proto_reference.html">Protos</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../../docs/release_notes.html">Release Notes</a></li>
<li class="toctree-l1"><a class="reference external" href="https://github.com/boston-dynamics/spot-sdk">SDK Repository</a></li>
</ul>

        </div>
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap"><nav class="wy-nav-top" aria-label="Mobile navigation menu" >
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../../../README.html">Spot</a>
      </nav>

      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="Page navigation">
  <ul class="wy-breadcrumbs">
      <li><a href="../../../README.html" class="icon icon-home" aria-label="Home"></a></li>
          <li class="breadcrumb-item"><a href="../../index.html">Module code</a></li>
      <li class="breadcrumb-item active">bosdyn.client.image_service_helpers</li>
      <li class="wy-breadcrumbs-aside">
      </li>
  </ul>
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
             
  <h1>Source code for bosdyn.client.image_service_helpers</h1><div class="highlight"><pre>
<span></span><span class="c1"># Copyright (c) 2023 Boston Dynamics, Inc.  All rights reserved.</span>
<span class="c1">#</span>
<span class="c1"># Downloading, reproducing, distributing or otherwise using the SDK Software</span>
<span class="c1"># is subject to the terms and conditions of the Boston Dynamics Software</span>
<span class="c1"># Development Kit License (20191101-BDSDK-SL).</span>

<span class="kn">import</span> <span class="nn">contextlib</span>
<span class="kn">import</span> <span class="nn">inspect</span>
<span class="kn">import</span> <span class="nn">logging</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">threading</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">from</span> <span class="nn">abc</span> <span class="kn">import</span> <span class="n">ABC</span><span class="p">,</span> <span class="n">abstractmethod</span>

<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>

<span class="kn">from</span> <span class="nn">bosdyn.api</span> <span class="kn">import</span> <span class="p">(</span><span class="n">header_pb2</span><span class="p">,</span> <span class="n">image_pb2</span><span class="p">,</span> <span class="n">image_service_pb2</span><span class="p">,</span> <span class="n">image_service_pb2_grpc</span><span class="p">,</span>
                        <span class="n">service_customization_pb2</span><span class="p">,</span> <span class="n">service_fault_pb2</span><span class="p">)</span>
<span class="kn">from</span> <span class="nn">bosdyn.client.data_buffer</span> <span class="kn">import</span> <span class="n">DataBufferClient</span>
<span class="kn">from</span> <span class="nn">bosdyn.client.exceptions</span> <span class="kn">import</span> <span class="n">RpcError</span>
<span class="kn">from</span> <span class="nn">bosdyn.client.fault</span> <span class="kn">import</span> <span class="p">(</span><span class="n">FaultClient</span><span class="p">,</span> <span class="n">ServiceFaultAlreadyExistsError</span><span class="p">,</span>
                                 <span class="n">ServiceFaultDoesNotExistError</span><span class="p">)</span>
<span class="kn">from</span> <span class="nn">bosdyn.client.image</span> <span class="kn">import</span> <span class="n">UnsupportedPixelFormatRequestedError</span>
<span class="kn">from</span> <span class="nn">bosdyn.client.server_util</span> <span class="kn">import</span> <span class="n">ResponseContext</span><span class="p">,</span> <span class="n">populate_response_header</span>
<span class="kn">from</span> <span class="nn">bosdyn.client.service_customization_helpers</span> <span class="kn">import</span> <span class="n">create_value_validator</span><span class="p">,</span> <span class="n">validate_dict_spec</span>
<span class="kn">from</span> <span class="nn">bosdyn.client.util</span> <span class="kn">import</span> <span class="n">setup_logging</span>
<span class="kn">from</span> <span class="nn">bosdyn.util</span> <span class="kn">import</span> <span class="n">sec_to_nsec</span><span class="p">,</span> <span class="n">seconds_to_duration</span>

<span class="n">_LOGGER</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>

<span class="n">CLEAR_FAULT_RPC_TIMEOUT_SECS</span> <span class="o">=</span> <span class="mf">0.1</span>


<div class="viewcode-block" id="convert_RGB_to_grayscale"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.convert_RGB_to_grayscale">[docs]</a><span class="k">def</span> <span class="nf">convert_RGB_to_grayscale</span><span class="p">(</span><span class="n">image_data_RGB_np</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Convert numpy image from RGB to grayscale using Pillow&#39;s formula.</span>

<span class="sd">    Args:</span>
<span class="sd">        image_data_RGB_np (numpy array): The RGB image data output from a capture as a 3D numpy</span>
<span class="sd">        array with R, G, B channels in that order in the array.</span>
<span class="sd">    Returns:</span>
<span class="sd">        Converted image_data_np as another 2D numpy array.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="c1"># gray = 0.299 * red + 0.587 * green + 0.114 * blue</span>
    <span class="c1"># This code performs the above math using integer math and bit shifts for speed.</span>
    <span class="c1"># The constants below are the same as the ones in the above equation multiplied by 2^16</span>
    <span class="c1"># The final addition makes it round the correct direction when it gets truncated by the bit shift.</span>
    <span class="n">rgb</span> <span class="o">=</span> <span class="n">image_data_RGB_np</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">uint32</span><span class="p">)</span>
    <span class="k">return</span> <span class="p">(</span>
        <span class="p">(</span><span class="n">rgb</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="mi">19595</span> <span class="o">+</span> <span class="n">rgb</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">1</span><span class="p">]</span> <span class="o">*</span> <span class="mi">38470</span> <span class="o">+</span> <span class="n">rgb</span><span class="p">[:,</span> <span class="p">:,</span> <span class="mi">2</span><span class="p">]</span> <span class="o">*</span> <span class="mi">7471</span> <span class="o">+</span> <span class="mh">0x8000</span><span class="p">)</span> <span class="o">&gt;&gt;</span> <span class="mi">16</span><span class="p">)</span><span class="o">.</span><span class="n">astype</span><span class="p">(</span>
            <span class="n">np</span><span class="o">.</span><span class="n">uint8</span><span class="p">)</span></div>


<div class="viewcode-block" id="CameraInterface"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.CameraInterface">[docs]</a><span class="k">class</span> <span class="nc">CameraInterface</span><span class="p">(</span><span class="n">ABC</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Abstract class interface for capturing and decoding images from a camera.</span>

<span class="sd">    This interface is used by the VisualImageSource to ensure that each image source</span>
<span class="sd">    has the expected capture and decoding methods with the right specification.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">capture_lock</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Lock</span><span class="p">()</span>

<div class="viewcode-block" id="CameraInterface.blocking_capture"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.CameraInterface.blocking_capture">[docs]</a>    <span class="nd">@abstractmethod</span>
    <span class="k">def</span> <span class="nf">blocking_capture</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">*</span><span class="p">,</span> <span class="n">custom_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Communicates with the camera payload to collect the image data. Ensure this is threadsafe as multiple</span>
<span class="sd">        threads/requests may try to call blocking_capture at the same time. A Lock (self.capture_lock) is provided</span>
<span class="sd">        as a convenience to help with this.</span>

<span class="sd">        Args:</span>
<span class="sd">            custom_params (service_customization_pb2.DictParam): Custom parameters defined by the image source</span>
<span class="sd">                                                                 affecting the resulting capture</span>
<span class="sd">            **kwargs: Other keyword arguments including future additions to the request that affect the capture.</span>
<span class="sd">                      If an implementer is looking to use kwargs, it is expected that they update their</span>
<span class="sd">                      blocking_capture function signature to accept named keyword arguments such as custom_params</span>

<span class="sd">        Returns:</span>
<span class="sd">            A tuple with image data (in any format), and the capture timestamp in seconds (float) in the</span>
<span class="sd">            service computer&#39;s clock.</span>
<span class="sd">        &quot;&quot;&quot;</span></div>

<div class="viewcode-block" id="CameraInterface.image_decode"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.CameraInterface.image_decode">[docs]</a>    <span class="nd">@abstractmethod</span>
    <span class="k">def</span> <span class="nf">image_decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_data</span><span class="p">,</span> <span class="n">image_proto</span><span class="p">,</span> <span class="n">image_req</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Decode the image data into an Image proto based on the requested format and quality.</span>

<span class="sd">        Args:</span>
<span class="sd">            image_data (Same format as the output of blocking_capture): The image data output from a capture.</span>
<span class="sd">            image_proto (image_pb2.Image): The proto message to populate with decoded image data.</span>
<span class="sd">            image_req (image_pb2.ImageRequest): The image request associated with the image_data.</span>

<span class="sd">        Returns:</span>
<span class="sd">            None.  Mutates the image_proto message with the decoded data. This function should set the image data,</span>
<span class="sd">            pixel format, image format, and potentially the transform snapshot fields within the image_proto</span>
<span class="sd">            protobuf message.</span>
<span class="sd">        &quot;&quot;&quot;</span></div></div>


<div class="viewcode-block" id="VisualImageSource"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.VisualImageSource">[docs]</a><span class="k">class</span> <span class="nc">VisualImageSource</span><span class="p">():</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Helper class to represent a single image source.</span>

<span class="sd">    This helper class can be used to track state associated with an image source. It can capture</span>
<span class="sd">    images and decode image data for an image service.</span>
<span class="sd">    It can be configured to:</span>
<span class="sd">    - throw faults for capture or decode failures</span>
<span class="sd">    - request images continuously on a background thread to allow image services to respond more</span>
<span class="sd">    rapidly to GetImage requests.</span>

<span class="sd">    Args:</span>
<span class="sd">        image_name (string): The name of the image source.</span>
<span class="sd">        camera_interface (subclass of CameraInterface): A camera class which inherits from and implements</span>
<span class="sd">                                                        the abstract methods of the CameraInterface class.</span>
<span class="sd">        rows (int): The number of rows of pixels in the image.</span>
<span class="sd">        cols (int): The number of cols of pixels in the image.</span>
<span class="sd">        gain (float | function): The sensor&#39;s gain in dB. This can be a fixed value or a function</span>
<span class="sd">                                 which returns the gain as a float.</span>
<span class="sd">        exposure (float | function): The exposure time for an image in seconds. This can be a fixed</span>
<span class="sd">                                     value or a function which returns the exposure time as a float.</span>
<span class="sd">        pixel_formats (image_pb2.Image.PixelFormat[]): Supported pixel formats.</span>
<span class="sd">        param_spec (service_customization_pb2.DictParam.Spec): A set of custom parameters passed into this</span>
<span class="sd">                                                               image source</span>
<span class="sd">        logger (logging.Logger): Logger for debug and warning messages.</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_name</span><span class="p">,</span> <span class="n">camera_interface</span><span class="p">,</span> <span class="n">rows</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">cols</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">gain</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">exposure</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                 <span class="n">pixel_formats</span><span class="o">=</span><span class="p">[],</span> <span class="n">logger</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">param_spec</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">image_source_name</span> <span class="o">=</span> <span class="n">image_name</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">supported_pixel_formats</span> <span class="o">=</span> <span class="n">pixel_formats</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">image_source_proto</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">make_image_source</span><span class="p">(</span><span class="n">image_name</span><span class="p">,</span> <span class="n">rows</span><span class="p">,</span> <span class="n">cols</span><span class="p">,</span>
                                                         <span class="bp">self</span><span class="o">.</span><span class="n">supported_pixel_formats</span><span class="p">,</span>
                                                         <span class="n">param_spec</span><span class="o">=</span><span class="n">param_spec</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">get_image_capture_params</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">request_custom_params</span><span class="o">=</span><span class="kc">None</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">make_capture_parameters</span><span class="p">(</span>
            <span class="n">gain</span><span class="o">=</span><span class="n">gain</span><span class="p">,</span> <span class="n">exposure</span><span class="o">=</span><span class="n">exposure</span><span class="p">,</span> <span class="n">request_custom_params</span><span class="o">=</span><span class="n">request_custom_params</span><span class="p">)</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">param_spec</span> <span class="o">=</span> <span class="n">param_spec</span>
        <span class="k">if</span> <span class="n">param_spec</span><span class="p">:</span>
            <span class="c1">#Fail fast if the spec being used is invalid, and otherwise get a function to easily validate values</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">value_validator</span> <span class="o">=</span> <span class="n">create_value_validator</span><span class="p">(</span><span class="n">param_spec</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1">#Validate against empty parameter set</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">value_validator</span> <span class="o">=</span> <span class="n">create_value_validator</span><span class="p">(</span>
                <span class="n">service_customization_pb2</span><span class="o">.</span><span class="n">DictParam</span><span class="o">.</span><span class="n">Spec</span><span class="p">())</span>
        <span class="c1"># Ensure the camera_interface is a subclass of CameraInterface and has the defined capture and</span>
        <span class="c1"># decode methods.</span>
        <span class="k">assert</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">camera_interface</span><span class="p">,</span> <span class="n">CameraInterface</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">camera_interface</span> <span class="o">=</span> <span class="n">camera_interface</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">capture_function</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">custom_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">_do_capture_with_error_checking</span><span class="p">(</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">camera_interface</span><span class="o">.</span><span class="n">blocking_capture</span><span class="p">,</span> <span class="n">custom_params</span><span class="o">=</span><span class="n">custom_params</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>

        <span class="c1"># Optional background thread to continuously capture image data. This will help an image</span>
        <span class="c1"># service to respond quickly to a GetImage request, since it can use the last captured image.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">capture_thread</span> <span class="o">=</span> <span class="kc">None</span>

        <span class="c1"># Fault client to report errors. Requires the image service name to</span>
        <span class="c1"># properly create the fault id.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">fault_client</span> <span class="o">=</span> <span class="kc">None</span>

        <span class="c1"># Create fault to throw if a failure occurs when calling the blocking_capture function.</span>
        <span class="n">camera_capture_fault_id</span> <span class="o">=</span> <span class="n">service_fault_pb2</span><span class="o">.</span><span class="n">ServiceFaultId</span><span class="p">(</span>
            <span class="n">fault_name</span><span class="o">=</span><span class="s2">&quot;Image Capture Failure for </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">image_source_name</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">camera_capture_fault</span> <span class="o">=</span> <span class="n">service_fault_pb2</span><span class="o">.</span><span class="n">ServiceFault</span><span class="p">(</span>
            <span class="n">fault_id</span><span class="o">=</span><span class="n">camera_capture_fault_id</span><span class="p">,</span> <span class="n">severity</span><span class="o">=</span><span class="n">service_fault_pb2</span><span class="o">.</span><span class="n">ServiceFault</span><span class="o">.</span><span class="n">SEVERITY_WARN</span><span class="p">)</span>
        <span class="c1"># Create a fault to throw if a failure occurs when calling the image_decode function.</span>
        <span class="n">decode_data_fault_id</span> <span class="o">=</span> <span class="n">service_fault_pb2</span><span class="o">.</span><span class="n">ServiceFaultId</span><span class="p">(</span>
            <span class="n">fault_name</span><span class="o">=</span><span class="s2">&quot;Decoding Image </span><span class="si">%s</span><span class="s2"> Failure&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">image_source_name</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">decode_data_fault</span> <span class="o">=</span> <span class="n">service_fault_pb2</span><span class="o">.</span><span class="n">ServiceFault</span><span class="p">(</span>
            <span class="n">fault_id</span><span class="o">=</span><span class="n">decode_data_fault_id</span><span class="p">,</span> <span class="n">severity</span><span class="o">=</span><span class="n">service_fault_pb2</span><span class="o">.</span><span class="n">ServiceFault</span><span class="o">.</span><span class="n">SEVERITY_WARN</span><span class="p">)</span>

        <span class="c1"># This is the set of active fault id names that can potentially get cleared.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">active_fault_id_names</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>

        <span class="c1"># Logger for warning messages and the last error message (used only when the background thread</span>
        <span class="c1"># is capturing such that error messages from the last capture can be shown still).</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">logger</span> <span class="o">=</span> <span class="n">logger</span> <span class="ow">or</span> <span class="n">_LOGGER</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">last_error_message</span> <span class="o">=</span> <span class="kc">None</span>

<div class="viewcode-block" id="VisualImageSource.set_logger"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.VisualImageSource.set_logger">[docs]</a>    <span class="k">def</span> <span class="nf">set_logger</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">logger</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Override the existing logger for the VisualImageSource class.&quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">logger</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">logger</span> <span class="o">=</span> <span class="n">logger</span></div>

<div class="viewcode-block" id="VisualImageSource.create_capture_thread"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.VisualImageSource.create_capture_thread">[docs]</a>    <span class="k">def</span> <span class="nf">create_capture_thread</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">custom_params</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Initialize a background thread to continuously capture images.</span>

<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">capture_thread</span> <span class="o">=</span> <span class="n">ImageCaptureThread</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">image_source_name</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">capture_function</span><span class="p">,</span>
                                                 <span class="n">custom_params</span><span class="o">=</span><span class="n">custom_params</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">capture_thread</span><span class="o">.</span><span class="n">start_capturing</span><span class="p">()</span></div>

<div class="viewcode-block" id="VisualImageSource.initialize_faults"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.VisualImageSource.initialize_faults">[docs]</a>    <span class="k">def</span> <span class="nf">initialize_faults</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fault_client</span><span class="p">,</span> <span class="n">image_service</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Initialize a fault client and faults for the image source (linked to the image service).</span>

<span class="sd">        The fault client can be used to throw faults for capture and decode errors. All faults</span>
<span class="sd">        associated with the image service name provided will be cleared.</span>

<span class="sd">        Args:</span>
<span class="sd">            fault_client (FaultClient): The fault client to communicate with the robot.</span>
<span class="sd">            image_service (string): The image service name to associate faults with.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">fault_client</span> <span class="o">=</span> <span class="n">fault_client</span>

        <span class="c1"># Update the fault ids to include the correct image service name.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">camera_capture_fault</span><span class="o">.</span><span class="n">fault_id</span><span class="o">.</span><span class="n">service_name</span> <span class="o">=</span> <span class="n">image_service</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">decode_data_fault</span><span class="o">.</span><span class="n">fault_id</span><span class="o">.</span><span class="n">service_name</span> <span class="o">=</span> <span class="n">image_service</span>

        <span class="c1"># Attempt to clear any previous faults for the image service.</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fault_client</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">fault_client</span><span class="o">.</span><span class="n">clear_service_fault</span><span class="p">(</span>
                    <span class="n">service_fault_pb2</span><span class="o">.</span><span class="n">ServiceFaultId</span><span class="p">(</span><span class="n">service_name</span><span class="o">=</span><span class="n">image_service</span><span class="p">),</span>
                    <span class="n">clear_all_service_faults</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
            <span class="k">except</span> <span class="n">ServiceFaultDoesNotExistError</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">active_fault_id_names</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
            <span class="k">except</span> <span class="n">RpcError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;RPC error in initialize_faults: </span><span class="si">%s</span><span class="s2">.&quot;</span><span class="p">,</span> <span class="n">exc</span><span class="p">)</span></div>

<div class="viewcode-block" id="VisualImageSource.trigger_fault"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.VisualImageSource.trigger_fault">[docs]</a>    <span class="k">def</span> <span class="nf">trigger_fault</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">error_message</span><span class="p">,</span> <span class="n">fault</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Trigger a service fault for a failure to the fault service.</span>

<span class="sd">        Args:</span>
<span class="sd">            error_message (string): The error message to provide in the camera capture fault.</span>
<span class="sd">            fault (service_fault_pb2.ServiceFault): The complete service fault to be issued.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fault_client</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">fault</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">fault</span><span class="o">.</span><span class="n">error_message</span> <span class="o">=</span> <span class="n">error_message</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">fault_client</span><span class="o">.</span><span class="n">trigger_service_fault</span><span class="p">(</span><span class="n">fault</span><span class="p">)</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">active_fault_id_names</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">fault</span><span class="o">.</span><span class="n">fault_id</span><span class="o">.</span><span class="n">fault_name</span><span class="p">)</span>
            <span class="k">except</span> <span class="n">ServiceFaultAlreadyExistsError</span><span class="p">:</span>
                <span class="k">pass</span>
            <span class="k">except</span> <span class="n">RpcError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;RPC error in trigger_fault: </span><span class="si">%s</span><span class="s2">.&quot;</span><span class="p">,</span> <span class="n">exc</span><span class="p">)</span></div>

<div class="viewcode-block" id="VisualImageSource.clear_fault"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.VisualImageSource.clear_fault">[docs]</a>    <span class="k">def</span> <span class="nf">clear_fault</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fault</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Attempts to clear the camera capture fault from the fault service.</span>

<span class="sd">        Args:</span>
<span class="sd">            fault (service_fault_pb2.ServiceFault): The fault (which contains an ID) to be cleared.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fault_client</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">fault</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">fault</span><span class="o">.</span><span class="n">fault_id</span><span class="o">.</span><span class="n">fault_name</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">active_fault_id_names</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">fault_client</span><span class="o">.</span><span class="n">clear_service_fault</span><span class="p">(</span><span class="n">fault</span><span class="o">.</span><span class="n">fault_id</span><span class="p">,</span>
                                                          <span class="n">timeout</span><span class="o">=</span><span class="n">CLEAR_FAULT_RPC_TIMEOUT_SECS</span><span class="p">)</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">active_fault_id_names</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">fault</span><span class="o">.</span><span class="n">fault_id</span><span class="o">.</span><span class="n">fault_name</span><span class="p">)</span>
            <span class="k">except</span> <span class="n">ServiceFaultDoesNotExistError</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&quot;No service fault found to clear.&quot;</span><span class="p">)</span>
            <span class="k">except</span> <span class="n">RpcError</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;RPC error in clear_fault: </span><span class="si">%s</span><span class="s2">.&quot;</span><span class="p">,</span> <span class="n">exc</span><span class="p">)</span></div>

    <span class="k">def</span> <span class="nf">_maybe_log_error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">error_message</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">show_last_error</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Logs the error message if it is new (to prevent spam).</span>

<span class="sd">        Args:</span>
<span class="sd">            error_message (string): The new error message.</span>
<span class="sd">            show_last_error (Boolean): If true, the error message will be logged even if it is not new.</span>

<span class="sd">        Returns:</span>
<span class="sd">            None. Logs messages to the logger.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">error_message</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">last_error_message</span> <span class="o">=</span> <span class="n">error_message</span>
        <span class="k">if</span> <span class="n">show_last_error</span><span class="p">:</span>
            <span class="c1"># force the printout of the last error message by sending the log message at a logger level</span>
            <span class="c1"># high enough to not be filtered out.</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">last_error_message</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="n">error_message</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">_do_capture_with_error_checking</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">capture_func</span><span class="p">,</span> <span class="n">custom_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                                        <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Calls the blocking capture function and checks for any exceptions.</span>

<span class="sd">        This function will print warning messages and trigger a camera capture fault if an</span>
<span class="sd">        exception is thrown by the camera interface&#39;s blocking capture function.</span>

<span class="sd">        Args:</span>
<span class="sd">            capture_func (CameraInterface.blocking_capture): The function capturing the image</span>
<span class="sd">                                                              data and timestamp.</span>
<span class="sd">            custom_params (service_customization_pb2.DictParam): Custom parameters passed to the blocking</span>
<span class="sd">                                                                 capture affecting the resulting capture</span>
<span class="sd">            **capture_func_kwargs: Other keyword arguments for the capture_func</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">custom_params</span> <span class="ow">or</span> <span class="n">capture_func_kwargs</span><span class="p">:</span>
                <span class="c1"># If supplying custom_params, try a blocking capture function that can handle them</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="n">img</span><span class="p">,</span> <span class="n">timestamp</span> <span class="o">=</span> <span class="n">capture_func</span><span class="p">(</span><span class="n">custom_params</span><span class="o">=</span><span class="n">custom_params</span><span class="p">,</span>
                                                  <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">)</span>
                <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
                    <span class="n">img</span><span class="p">,</span> <span class="n">timestamp</span> <span class="o">=</span> <span class="n">capture_func</span><span class="p">()</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="c1"># Supports pre-3.3 blocking_capture if no custom_params or kwargs (both introduced in 3.3) are passed</span>
                <span class="n">img</span><span class="p">,</span> <span class="n">timestamp</span> <span class="o">=</span> <span class="n">capture_func</span><span class="p">()</span>
            <span class="c1"># Clear out any old error messages if the capture succeeds.</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">last_error_message</span> <span class="o">=</span> <span class="kc">None</span>
            <span class="c1"># Clear any previous camera capture faults after a successful image capture for</span>
            <span class="c1"># this image source.</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">clear_fault</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">camera_capture_fault</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">img</span><span class="p">,</span> <span class="n">timestamp</span>
        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
            <span class="n">error_message</span> <span class="o">=</span> <span class="s2">&quot;Failed to capture an image from </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">image_source_name</span><span class="p">,</span>
                                                                           <span class="nb">type</span><span class="p">(</span><span class="n">err</span><span class="p">),</span> <span class="n">err</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_maybe_log_error</span><span class="p">(</span><span class="n">error_message</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">trigger_fault</span><span class="p">(</span><span class="n">error_message</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">camera_capture_fault</span><span class="p">)</span>
            <span class="k">return</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span>

<div class="viewcode-block" id="VisualImageSource.get_image_and_timestamp"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.VisualImageSource.get_image_and_timestamp">[docs]</a>    <span class="k">def</span> <span class="nf">get_image_and_timestamp</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">custom_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Retrieve the latest captured image and timestamp.</span>

<span class="sd">        Args:</span>
<span class="sd">            custom_params (service_customization_pb2.DictParam): Custom parameters passed to the object&#39;s</span>
<span class="sd">                                                                 capture_function affecting the resulting capture</span>
<span class="sd">            **capture_func_kwargs: Other keyword arguments for the capture_function</span>

<span class="sd">        Returns:</span>
<span class="sd">            The latest captured image and the time (in seconds) associated with that image capture.</span>
<span class="sd">            Throws a camera capture fault and returns None if the image cannot be retrieved.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">capture_thread</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">thread_capture_output</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">capture_thread</span><span class="o">.</span><span class="n">get_latest_captured_image</span><span class="p">(</span>
                <span class="n">custom_params</span><span class="o">=</span><span class="n">custom_params</span><span class="p">,</span> <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">)</span>
            <span class="n">valid_thread_capture</span><span class="p">,</span> <span class="n">image</span><span class="p">,</span> <span class="n">timestamp</span> <span class="o">=</span> <span class="n">thread_capture_output</span><span class="o">.</span><span class="n">is_valid</span><span class="p">,</span> <span class="n">thread_capture_output</span><span class="o">.</span><span class="n">image</span><span class="p">,</span> <span class="n">thread_capture_output</span><span class="o">.</span><span class="n">timestamp</span>
            <span class="k">if</span> <span class="n">valid_thread_capture</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">image</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">timestamp</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                    <span class="c1"># Force the printout of the last error message since the capture failed.</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">_maybe_log_error</span><span class="p">(</span><span class="n">show_last_error</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
                <span class="k">return</span> <span class="n">image</span><span class="p">,</span> <span class="n">timestamp</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">capture_function</span><span class="p">(</span><span class="n">custom_params</span><span class="o">=</span><span class="n">custom_params</span><span class="p">,</span> <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c1"># Call the capture function (which is wrapped with an error checker) to block and get the data.</span>
            <span class="c1"># capture_function already handles pre-3.3 blocking capture compatibility</span>
            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">capture_function</span><span class="p">(</span><span class="n">custom_params</span><span class="o">=</span><span class="n">custom_params</span><span class="p">,</span> <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">)</span></div>

<div class="viewcode-block" id="VisualImageSource.image_decode_with_error_checking"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.VisualImageSource.image_decode_with_error_checking">[docs]</a>    <span class="k">def</span> <span class="nf">image_decode_with_error_checking</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_data</span><span class="p">,</span> <span class="n">image_proto</span><span class="p">,</span> <span class="n">image_req</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Decode the image data into an Image proto based on the requested format and quality.</span>

<span class="sd">        Args:</span>
<span class="sd">            image_data(any format): The image data returned by the camera interface&#39;s</span>
<span class="sd">                                    blocking_capture function.</span>
<span class="sd">            image_proto (image_pb2.Image): The image proto to be mutated with the decoded data.</span>
<span class="sd">            image_req (image_pb2.ImageRequest): The image request associated with the image_data.</span>

<span class="sd">        Returns:</span>
<span class="sd">            image_pb2.ImageResponse.Status indicating if the decoding succeeds, or image format conversion or</span>
<span class="sd">            pixel conversion failed. Throws a decode data fault if the image or</span>
<span class="sd">            pixels cannot be decoded to the desired format. Mutates the image_proto Image proto</span>
<span class="sd">            with the decoded data if successful.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">decode_format</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="n">quality_percent</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="n">pixel_format</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="k">if</span> <span class="n">image_req</span><span class="p">:</span>
            <span class="n">decode_format</span> <span class="o">=</span> <span class="n">image_req</span><span class="o">.</span><span class="n">image_format</span>
            <span class="n">quality_percent</span> <span class="o">=</span> <span class="n">image_req</span><span class="o">.</span><span class="n">quality_percent</span>
            <span class="n">pixel_format</span> <span class="o">=</span> <span class="n">image_req</span><span class="o">.</span><span class="n">pixel_format</span>
            <span class="k">if</span> <span class="n">pixel_format</span> <span class="ow">and</span> <span class="p">(</span><span class="n">pixel_format</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">supported_pixel_formats</span><span class="p">):</span>
                <span class="k">return</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">ImageResponse</span><span class="o">.</span><span class="n">STATUS_UNSUPPORTED_PIXEL_FORMAT_REQUESTED</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="c1"># Older function definition did not have image_req</span>
            <span class="c1"># Try/except for backwards compatibility</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">camera_interface</span><span class="o">.</span><span class="n">image_decode</span><span class="p">(</span><span class="n">image_data</span><span class="p">,</span> <span class="n">image_proto</span><span class="p">,</span> <span class="n">image_req</span><span class="p">)</span>
            <span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">camera_interface</span><span class="o">.</span><span class="n">image_decode</span><span class="p">(</span><span class="n">image_data</span><span class="p">,</span> <span class="n">image_proto</span><span class="p">,</span> <span class="n">decode_format</span><span class="p">,</span>
                                                   <span class="n">quality_percent</span><span class="p">)</span>
            <span class="c1"># Clear any previous decode data faults after a successful decoding by this image source.</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">clear_fault</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">decode_data_fault</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">ImageResponse</span><span class="o">.</span><span class="n">STATUS_OK</span>
        <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
            <span class="n">decode_format_str</span> <span class="o">=</span> <span class="kc">None</span>
            <span class="k">if</span> <span class="n">decode_format</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">decode_format_str</span> <span class="o">=</span> <span class="s2">&quot;unknown format&quot;</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">decode_format_str</span> <span class="o">=</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">Image</span><span class="o">.</span><span class="n">Format</span><span class="o">.</span><span class="n">Name</span><span class="p">(</span><span class="n">decode_format</span><span class="p">)</span>
            <span class="n">error_message</span> <span class="o">=</span> <span class="s2">&quot;Failed to decode image </span><span class="si">%s</span><span class="s2"> to format </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2"> </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">image_source_name</span><span class="p">,</span> <span class="n">decode_format_str</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="n">err</span><span class="p">),</span> <span class="n">err</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">_maybe_log_error</span><span class="p">(</span><span class="n">error_message</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">trigger_fault</span><span class="p">(</span><span class="n">error_message</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">decode_data_fault</span><span class="p">)</span>
            <span class="k">return</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">ImageResponse</span><span class="o">.</span><span class="n">STATUS_UNSUPPORTED_IMAGE_FORMAT_REQUESTED</span></div>

<div class="viewcode-block" id="VisualImageSource.stop_capturing"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.VisualImageSource.stop_capturing">[docs]</a>    <span class="k">def</span> <span class="nf">stop_capturing</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeout_secs</span><span class="o">=</span><span class="mi">10</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Stop the image capture thread if one exists.</span>

<span class="sd">        Args:</span>
<span class="sd">            timeout_secs(int): The timeout [seconds] for attempting to join and destroy the capture thread.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">capture_thread</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">capture_thread</span><span class="o">.</span><span class="n">stop_capturing</span><span class="p">(</span><span class="n">timeout_secs</span><span class="p">)</span></div>

<div class="viewcode-block" id="VisualImageSource.make_image_source"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.VisualImageSource.make_image_source">[docs]</a>    <span class="nd">@staticmethod</span>
    <span class="k">def</span> <span class="nf">make_image_source</span><span class="p">(</span><span class="n">source_name</span><span class="p">,</span> <span class="n">rows</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">cols</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">pixel_formats</span><span class="o">=</span><span class="p">[],</span>
                          <span class="n">image_type</span><span class="o">=</span><span class="n">image_pb2</span><span class="o">.</span><span class="n">ImageSource</span><span class="o">.</span><span class="n">IMAGE_TYPE_VISUAL</span><span class="p">,</span>
                          <span class="n">image_formats</span><span class="o">=</span><span class="p">[</span><span class="n">image_pb2</span><span class="o">.</span><span class="n">Image</span><span class="o">.</span><span class="n">FORMAT_JPEG</span><span class="p">],</span> <span class="n">param_spec</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Create an instance of the image_pb2.ImageSource for a given source name.</span>

<span class="sd">        Args:</span>
<span class="sd">            source_name (string): The name for the camera source.</span>
<span class="sd">            rows (int): The number of rows of pixels in the image.</span>
<span class="sd">            cols (int): The number of cols of pixels in the image.</span>
<span class="sd">            image_type (image_pb2.ImageType): The type of image (e.g. visual, depth).</span>
<span class="sd">            image_formats (image_pb2.Image.Format): The image formats supported (jpeg, raw)</span>
<span class="sd">            pixel_formats (image_pb2.Image.PixelFormat): The pixel formats supported</span>
<span class="sd">            param_spec (service_customization_pb2.DictParam.Spec): A set of custom parameters</span>
<span class="sd">                                                                   passed into this image source</span>
<span class="sd">        Returns:</span>
<span class="sd">            An ImageSource with the cols, rows, and image type populated.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">source</span> <span class="o">=</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">ImageSource</span><span class="p">()</span>
        <span class="n">source</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">source_name</span>

        <span class="k">if</span> <span class="n">rows</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">cols</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">source</span><span class="o">.</span><span class="n">rows</span> <span class="o">=</span> <span class="n">rows</span>
            <span class="n">source</span><span class="o">.</span><span class="n">cols</span> <span class="o">=</span> <span class="n">cols</span>

        <span class="c1"># Image from the ricoh theta is a JPEG, which is considered a visual image source (no depth data).</span>
        <span class="n">source</span><span class="o">.</span><span class="n">image_type</span> <span class="o">=</span> <span class="n">image_type</span>
        <span class="n">source</span><span class="o">.</span><span class="n">image_formats</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">image_formats</span><span class="p">)</span>
        <span class="n">source</span><span class="o">.</span><span class="n">pixel_formats</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">pixel_formats</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">param_spec</span><span class="p">:</span>
            <span class="n">source</span><span class="o">.</span><span class="n">custom_params</span><span class="o">.</span><span class="n">CopyFrom</span><span class="p">(</span><span class="n">param_spec</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">source</span></div>

<div class="viewcode-block" id="VisualImageSource.make_capture_parameters"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.VisualImageSource.make_capture_parameters">[docs]</a>    <span class="nd">@staticmethod</span>
    <span class="k">def</span> <span class="nf">make_capture_parameters</span><span class="p">(</span><span class="n">gain</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">exposure</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">request_custom_params</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Creates an instance of the image_pb2.CaptureParameters protobuf message.</span>

<span class="sd">        Args:</span>
<span class="sd">            gain (float | function): The sensor&#39;s gain in dB. This can be a fixed value or a function</span>
<span class="sd">                                     which returns the gain as a float.</span>
<span class="sd">            exposure (float | function): The exposure time for an image in seconds. This can be a fixed</span>
<span class="sd">                              value or a function which returns the exposure time as a float.</span>
<span class="sd">            request_custom_params (service_customization_pb2.DictParam): Custom Params associated with the image</span>
<span class="sd">                            request. Should not be &#39;None&#39;, but left as an option to accommodate old callers</span>
<span class="sd">        Returns:</span>
<span class="sd">            An instance of the protobuf CaptureParameters message.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">params</span> <span class="o">=</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">CaptureParameters</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">gain</span><span class="p">:</span>
            <span class="k">if</span> <span class="nb">callable</span><span class="p">(</span><span class="n">gain</span><span class="p">):</span>
                <span class="n">params</span><span class="o">.</span><span class="n">gain</span> <span class="o">=</span> <span class="n">gain</span><span class="p">()</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">params</span><span class="o">.</span><span class="n">gain</span> <span class="o">=</span> <span class="n">gain</span>
        <span class="k">if</span> <span class="n">exposure</span><span class="p">:</span>
            <span class="k">if</span> <span class="nb">callable</span><span class="p">(</span><span class="n">exposure</span><span class="p">):</span>
                <span class="n">params</span><span class="o">.</span><span class="n">exposure_duration</span><span class="o">.</span><span class="n">CopyFrom</span><span class="p">(</span><span class="n">seconds_to_duration</span><span class="p">(</span><span class="n">exposure</span><span class="p">()))</span>
            <span class="k">elif</span> <span class="n">exposure</span> <span class="o">==</span> <span class="nb">float</span><span class="p">(</span><span class="s1">&#39;inf&#39;</span><span class="p">):</span>
                <span class="n">params</span><span class="o">.</span><span class="n">exposure_duration</span><span class="o">.</span><span class="n">CopyFrom</span><span class="p">(</span><span class="n">seconds_to_duration</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">maxsize</span><span class="p">))</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">params</span><span class="o">.</span><span class="n">exposure_duration</span><span class="o">.</span><span class="n">CopyFrom</span><span class="p">(</span><span class="n">seconds_to_duration</span><span class="p">(</span><span class="n">exposure</span><span class="p">))</span>
        <span class="k">if</span> <span class="n">request_custom_params</span><span class="p">:</span>
            <span class="n">params</span><span class="o">.</span><span class="n">custom_params</span><span class="o">.</span><span class="n">CopyFrom</span><span class="p">(</span><span class="n">request_custom_params</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">params</span></div></div>


<div class="viewcode-block" id="ThreadCaptureOutput"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.ThreadCaptureOutput">[docs]</a><span class="k">class</span> <span class="nc">ThreadCaptureOutput</span><span class="p">:</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Small struct to represent the output of an ImageCaptureThread&#39;s get_latest_captured_image</span>
<span class="sd">    in a future-compatible way</span>

<span class="sd">    Args:</span>
<span class="sd">        is_valid (Boolean): Whether the latest capture uses the custom parameters and other arguments</span>
<span class="sd">                            supplied in the latest request, and is therefore returned</span>
<span class="sd">        image (Any | None): If the latest capture is valid, the image data in any format</span>
<span class="sd">                            (e.g. numpy, bytes, array)</span>
<span class="sd">        timestamp (float): The timestamp that the latest valid capture was taken</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">is_valid</span><span class="p">,</span> <span class="n">image</span><span class="p">,</span> <span class="n">timestamp</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">is_valid</span> <span class="o">=</span> <span class="n">is_valid</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">image</span> <span class="o">=</span> <span class="n">image</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">timestamp</span> <span class="o">=</span> <span class="n">timestamp</span></div>


<div class="viewcode-block" id="ImageCaptureThread"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.ImageCaptureThread">[docs]</a><span class="k">class</span> <span class="nc">ImageCaptureThread</span><span class="p">():</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;Continuously query and store the last successfully captured image and its</span>
<span class="sd">    associated timestamp for a single camera device.</span>

<span class="sd">    Args:</span>
<span class="sd">        image_source_name(string): The image source name.</span>
<span class="sd">        capture_func (CameraInterface.blocking_capture): The function capturing the image</span>
<span class="sd">                                                         data and timestamp.</span>
<span class="sd">        capture_period_secs (int): Amount of time (in seconds) between captures to wait</span>
<span class="sd">                                   before triggering the next capture. Defaults to</span>
<span class="sd">                                   0.05s between captures.</span>
<span class="sd">        custom_params (service_customization_pb2.DictParam): Custom parameters passed to capture_func</span>
<span class="sd">                                                             affecting the resulting capture</span>
<span class="sd">        **capture_func_kwargs: Other keyword arguments for the capture_func</span>
<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_source_name</span><span class="p">,</span> <span class="n">capture_func</span><span class="p">,</span> <span class="n">capture_period_secs</span><span class="o">=</span><span class="mf">0.05</span><span class="p">,</span>
                 <span class="n">custom_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">):</span>
        <span class="c1"># Name of the image source that is being requested from.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">image_source_name</span> <span class="o">=</span> <span class="n">image_source_name</span>

        <span class="c1"># Indicate if the image capture thread is alive.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">stop_capturing_event</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Event</span><span class="p">()</span>

        <span class="c1"># Track the last image and timestamp for this image source.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">last_captured_image</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">last_captured_time</span> <span class="o">=</span> <span class="kc">None</span>

        <span class="c1"># Has a capture with the latest parameters completed (not necessarily successfully)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">has_updated_capture</span> <span class="o">=</span> <span class="kc">False</span>

        <span class="c1"># Lock for the thread.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_thread_lock</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Lock</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_thread</span> <span class="o">=</span> <span class="kc">None</span>

        <span class="c1"># The wait time between captures.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">capture_period_secs</span> <span class="o">=</span> <span class="n">capture_period_secs</span>

        <span class="c1"># Custom parameters the thread is currently running with</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">custom_params</span> <span class="o">=</span> <span class="n">custom_params</span>

        <span class="c1">#Other keyword arguments the thread is currently running with</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">capture_func_kwargs</span> <span class="o">=</span> <span class="n">capture_func_kwargs</span>

        <span class="c1"># Original user-passed capture_func</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">init_capture_function</span> <span class="o">=</span> <span class="n">capture_func</span>

        <span class="c1"># Function that completes the capture</span>
        <span class="c1"># Expected function signature: blocking_capture_function(custom_params=None): returns (image data[numpy bytes array], time[float])</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">capture_function</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_make_capture_func</span><span class="p">(</span><span class="n">capture_func</span><span class="p">,</span> <span class="n">custom_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                                                        <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">)</span>

<div class="viewcode-block" id="ImageCaptureThread.start_capturing"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.ImageCaptureThread.start_capturing">[docs]</a>    <span class="k">def</span> <span class="nf">start_capturing</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Start the background thread for the image captures.&quot;&quot;&quot;</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Starting the thread for </span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">image_source_name</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_thread</span> <span class="o">=</span> <span class="n">threading</span><span class="o">.</span><span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_do_image_capture</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_thread</span><span class="o">.</span><span class="n">daemon</span> <span class="o">=</span> <span class="kc">True</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_thread</span><span class="o">.</span><span class="n">start</span><span class="p">()</span></div>

<div class="viewcode-block" id="ImageCaptureThread.maybe_update_thread"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.ImageCaptureThread.maybe_update_thread">[docs]</a>    <span class="k">def</span> <span class="nf">maybe_update_thread</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">custom_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">custom_params</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">custom_params</span> <span class="ow">or</span> <span class="n">capture_func_kwargs</span> <span class="o">!=</span> <span class="bp">self</span><span class="o">.</span><span class="n">capture_func_kwargs</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">capture_function</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_make_capture_func</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">init_capture_function</span><span class="p">,</span>
                                                            <span class="n">custom_params</span><span class="p">,</span> <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">custom_params</span> <span class="o">=</span> <span class="n">custom_params</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">capture_func_kwargs</span> <span class="o">=</span> <span class="n">capture_func_kwargs</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">has_updated_capture</span> <span class="o">=</span> <span class="kc">False</span></div>

<div class="viewcode-block" id="ImageCaptureThread.set_last_captured_image"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.ImageCaptureThread.set_last_captured_image">[docs]</a>    <span class="k">def</span> <span class="nf">set_last_captured_image</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_frame</span><span class="p">,</span> <span class="n">capture_time</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Update the last image capture and timestamp.&quot;&quot;&quot;</span>
        <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_thread_lock</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">last_captured_image</span> <span class="o">=</span> <span class="n">image_frame</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">last_captured_time</span> <span class="o">=</span> <span class="n">capture_time</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">has_updated_capture</span> <span class="o">=</span> <span class="kc">True</span></div>

<div class="viewcode-block" id="ImageCaptureThread.get_latest_captured_image"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.ImageCaptureThread.get_latest_captured_image">[docs]</a>    <span class="k">def</span> <span class="nf">get_latest_captured_image</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">custom_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Returns the last found image and timestamp in a ThreadCaptureOutput object if that</span>
<span class="sd">            image uses the latest params. Otherwise returns a ThreadCaptureOutput object with</span>
<span class="sd">            is_valid = False and capture/timestamp as None.</span>
<span class="sd">        &quot;&quot;&quot;</span>

        <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_thread_lock</span><span class="p">:</span>
            <span class="k">if</span> <span class="p">(</span><span class="n">custom_params</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">custom_params</span> <span class="ow">and</span>
                    <span class="n">capture_func_kwargs</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">capture_func_kwargs</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">has_updated_capture</span><span class="p">):</span>
                <span class="k">return</span> <span class="n">ThreadCaptureOutput</span><span class="p">(</span><span class="kc">True</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_captured_image</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_captured_time</span><span class="p">)</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">maybe_update_thread</span><span class="p">(</span><span class="n">custom_params</span><span class="o">=</span><span class="n">custom_params</span><span class="p">,</span> <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">)</span>
                <span class="k">return</span> <span class="n">ThreadCaptureOutput</span><span class="p">(</span><span class="kc">False</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span></div>

    <span class="k">def</span> <span class="nf">_make_capture_func</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">capture_func</span><span class="p">,</span> <span class="n">custom_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Update the capture function to use custom_params and capture_func_kwargs if it can&quot;&quot;&quot;</span>

        <span class="c1"># capture_func is likely provided through create_capture_thread, which already does handling for pre-3.3 blocking_capture</span>
        <span class="c1"># Still, check for the custom_params argument to ensure we accommodate pre-3.3 direct implementations of ImageCaptureThreads</span>
        <span class="k">if</span> <span class="s2">&quot;custom_params&quot;</span> <span class="ow">in</span> <span class="n">inspect</span><span class="o">.</span><span class="n">signature</span><span class="p">(</span><span class="n">capture_func</span><span class="p">)</span><span class="o">.</span><span class="n">parameters</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
            <span class="c1">#If using a blocking capture function that takes in custom params or kwargs, one should supply those</span>
            <span class="k">def</span> <span class="nf">output_capture_function</span><span class="p">():</span>
                <span class="k">return</span> <span class="n">capture_func</span><span class="p">(</span><span class="n">custom_params</span><span class="o">=</span><span class="n">custom_params</span><span class="p">,</span> <span class="o">**</span><span class="n">capture_func_kwargs</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">output_capture_function</span> <span class="o">=</span> <span class="n">capture_func</span>
        <span class="k">return</span> <span class="n">output_capture_function</span>

    <span class="k">def</span> <span class="nf">_do_image_capture</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Main loop for the image capture thread, which requests and saves images.&quot;&quot;&quot;</span>
        <span class="k">while</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">stop_capturing_event</span><span class="o">.</span><span class="n">is_set</span><span class="p">():</span>
            <span class="c1"># Get the image by calling the blocking capture function.</span>
            <span class="n">start_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
            <span class="n">capture</span><span class="p">,</span> <span class="n">capture_time</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">capture_function</span><span class="p">()</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">set_last_captured_image</span><span class="p">(</span><span class="n">capture</span><span class="p">,</span> <span class="n">capture_time</span><span class="p">)</span>

            <span class="c1"># Wait for the total capture period (where the wait time is adjusted based on how</span>
            <span class="c1"># long the capture took).</span>
            <span class="n">wait_time</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">capture_period_secs</span> <span class="o">-</span> <span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">start_time</span><span class="p">)</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">stop_capturing_event</span><span class="o">.</span><span class="n">wait</span><span class="p">(</span><span class="n">wait_time</span><span class="p">):</span>
                <span class="c1"># If stop_capturing_event is set, then break from the capture loop now.</span>
                <span class="k">break</span>

<div class="viewcode-block" id="ImageCaptureThread.stop_capturing"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.ImageCaptureThread.stop_capturing">[docs]</a>    <span class="k">def</span> <span class="nf">stop_capturing</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">timeout_secs</span><span class="o">=</span><span class="mi">10</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Stop the image capture thread.&quot;&quot;&quot;</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">stop_capturing_event</span><span class="o">.</span><span class="n">set</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_thread</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="n">timeout_secs</span><span class="p">)</span></div></div>


<div class="viewcode-block" id="CameraBaseImageServicer"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.CameraBaseImageServicer">[docs]</a><span class="k">class</span> <span class="nc">CameraBaseImageServicer</span><span class="p">(</span><span class="n">image_service_pb2_grpc</span><span class="o">.</span><span class="n">ImageServiceServicer</span><span class="p">):</span>
<span class="w">    </span><span class="sd">&quot;&quot;&quot;GRPC service to provide access to multiple different image sources.</span>

<span class="sd">    The service can list the available image (device) sources and query each source for image data.</span>

<span class="sd">    Args:</span>
<span class="sd">        bosdyn_sdk_robot (Robot): The robot instance for the service to connect to.</span>
<span class="sd">        service_name (string): The name of the image service.</span>
<span class="sd">        image_sources(List[VisualImageSource]): The list of image sources (provided as a VisualImageSource).</span>
<span class="sd">        logger (logging.Logger): Logger for debug and warning messages.</span>
<span class="sd">        use_background_capture_thread (bool): If true, the image service will create a thread that continuously</span>
<span class="sd">            captures images so the image service can respond rapidly to the GetImage request. If false,</span>
<span class="sd">            the image service will call an image sources&#39; blocking_capture_function during the GetImage request.</span>
<span class="sd">        background_capture_params (service_customization_pb2.DictParam): If use_background_capture_thread is true,</span>
<span class="sd">            custom image source parameters used for all of the background captures. Otherwise ignored</span>
<span class="sd">        log_images (bool): if true, include image request/response messages in robot logs.  This is turned off</span>
<span class="sd">            by default.</span>

<span class="sd">    &quot;&quot;&quot;</span>

    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">bosdyn_sdk_robot</span><span class="p">,</span> <span class="n">service_name</span><span class="p">,</span> <span class="n">image_sources</span><span class="p">,</span> <span class="n">logger</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                 <span class="n">use_background_capture_thread</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">background_capture_params</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
                 <span class="n">log_images</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">CameraBaseImageServicer</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="fm">__init__</span><span class="p">()</span>
        <span class="k">if</span> <span class="n">logger</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="c1"># Set up the logger to remove duplicated messages and use a specific logging format.</span>
            <span class="n">setup_logging</span><span class="p">(</span><span class="n">include_dedup_filter</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">logger</span> <span class="o">=</span> <span class="n">_LOGGER</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">logger</span> <span class="o">=</span> <span class="n">logger</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">bosdyn_sdk_robot</span> <span class="o">=</span> <span class="n">bosdyn_sdk_robot</span>

        <span class="c1"># Service name this servicer is associated with in the robot directory.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">service_name</span> <span class="o">=</span> <span class="n">service_name</span>

        <span class="c1"># Fault client to report service faults</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">fault_client</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">bosdyn_sdk_robot</span><span class="o">.</span><span class="n">ensure_client</span><span class="p">(</span><span class="n">FaultClient</span><span class="o">.</span><span class="n">default_service_name</span><span class="p">)</span>

        <span class="k">if</span> <span class="n">log_images</span><span class="p">:</span>
            <span class="c1"># Data buffer client for logging messages</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">data_buffer_client</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">bosdyn_sdk_robot</span><span class="o">.</span><span class="n">ensure_client</span><span class="p">(</span>
                <span class="n">DataBufferClient</span><span class="o">.</span><span class="n">default_service_name</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">data_buffer_client</span> <span class="o">=</span> <span class="kc">None</span>

        <span class="c1"># Get a timesync endpoint from the robot instance such that the image timestamps can be</span>
        <span class="c1"># reported in the robot&#39;s time.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">bosdyn_sdk_robot</span><span class="o">.</span><span class="n">time_sync</span><span class="o">.</span><span class="n">wait_for_sync</span><span class="p">()</span>

        <span class="c1"># A list of all the image sources available by this service. List[VisualImageSource]</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">image_sources_mapped</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">()</span>  <span class="c1"># Key: source name (string), Value: VisualImageSource</span>
        <span class="k">for</span> <span class="n">source</span> <span class="ow">in</span> <span class="n">image_sources</span><span class="p">:</span>
            <span class="c1"># Set the logger for each visual image source to be the logger of the camera service class.</span>
            <span class="n">source</span><span class="o">.</span><span class="n">set_logger</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="p">)</span>
            <span class="c1"># Set up the fault client so service faults can be created.</span>
            <span class="n">source</span><span class="o">.</span><span class="n">initialize_faults</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fault_client</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">service_name</span><span class="p">)</span>
            <span class="c1"># Potentially start the capture threads in the background.</span>
            <span class="k">if</span> <span class="n">use_background_capture_thread</span><span class="p">:</span>
                <span class="n">source</span><span class="o">.</span><span class="n">create_capture_thread</span><span class="p">(</span><span class="n">background_capture_params</span><span class="p">)</span>
            <span class="c1"># Save the visual image source class associated with the image source name.</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">image_sources_mapped</span><span class="p">[</span><span class="n">source</span><span class="o">.</span><span class="n">image_source_name</span><span class="p">]</span> <span class="o">=</span> <span class="n">source</span>

<div class="viewcode-block" id="CameraBaseImageServicer.ListImageSources"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.CameraBaseImageServicer.ListImageSources">[docs]</a>    <span class="k">def</span> <span class="nf">ListImageSources</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Obtain the list of ImageSources for this given service.</span>

<span class="sd">        Args:</span>
<span class="sd">            request (image_pb2.ListImageSourcesRequest): The list images request.</span>
<span class="sd">            context (GRPC ClientContext): tracks internal grpc statuses and information.</span>

<span class="sd">        Returns:</span>
<span class="sd">            A list of all image sources known to this image service. Note, there could be multiple image</span>
<span class="sd">            services registered with the robot&#39;s directory service that can have different image sources.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">response</span> <span class="o">=</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">ListImageSourcesResponse</span><span class="p">()</span>
        <span class="k">for</span> <span class="n">source</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">image_sources_mapped</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
            <span class="n">response</span><span class="o">.</span><span class="n">image_sources</span><span class="o">.</span><span class="n">add</span><span class="p">()</span><span class="o">.</span><span class="n">CopyFrom</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">image_source_proto</span><span class="p">)</span>
        <span class="n">populate_response_header</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">request</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">response</span></div>

    <span class="k">def</span> <span class="nf">_set_format_and_decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">image_data</span><span class="p">,</span> <span class="n">img_proto</span><span class="p">,</span> <span class="n">img_req</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Calls the image_decode_with_error_checking function, which returns a (Boolean, Boolean) if the decoding succeeds.&quot;&quot;&quot;</span>
        <span class="c1"># This function should set the image data, pixel format, image format, and transform snapshot fields.</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">image_sources_mapped</span><span class="p">[</span>
            <span class="n">img_req</span><span class="o">.</span><span class="n">image_source_name</span><span class="p">]</span><span class="o">.</span><span class="n">image_decode_with_error_checking</span><span class="p">(</span>
                <span class="n">image_data</span><span class="p">,</span> <span class="n">img_proto</span><span class="p">,</span> <span class="n">img_req</span><span class="p">)</span>

<div class="viewcode-block" id="CameraBaseImageServicer.GetImage"><a class="viewcode-back" href="../../../python/bosdyn-client/src/bosdyn/client/image_service_helpers.html#bosdyn.client.image_service_helpers.CameraBaseImageServicer.GetImage">[docs]</a>    <span class="k">def</span> <span class="nf">GetImage</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span>
<span class="w">        </span><span class="sd">&quot;&quot;&quot;Gets the latest image capture from all the image sources specified in the request.</span>

<span class="sd">        Args:</span>
<span class="sd">            request (image_pb2.GetImageRequest): The image request, which specifies the image sources to</span>
<span class="sd">                                                 query, and other format parameters.</span>
<span class="sd">            context (GRPC ClientContext): tracks internal grpc statuses and information.</span>

<span class="sd">        Returns:</span>
<span class="sd">            The ImageSource and Image data for the last captured image from each image source name</span>
<span class="sd">            specified in the request.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">response</span> <span class="o">=</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">GetImageResponse</span><span class="p">()</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">data_buffer_client</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">response_context</span> <span class="o">=</span> <span class="n">ResponseContext</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">data_buffer_client</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">response_context</span> <span class="o">=</span> <span class="n">contextlib</span><span class="o">.</span><span class="n">nullcontext</span><span class="p">()</span>
        <span class="k">with</span> <span class="n">response_context</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">img_req</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">image_requests</span><span class="p">:</span>
                <span class="n">img_resp</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">image_responses</span><span class="o">.</span><span class="n">add</span><span class="p">()</span>
                <span class="n">src_name</span> <span class="o">=</span> <span class="n">img_req</span><span class="o">.</span><span class="n">image_source_name</span>
                <span class="k">if</span> <span class="n">src_name</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">image_sources_mapped</span><span class="p">:</span>
                    <span class="c1"># The requested camera source does not match the name of the Ricoh Theta camera, so it cannot</span>
                    <span class="c1"># be completed and will have a failure status in the response message.</span>
                    <span class="n">img_resp</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">ImageResponse</span><span class="o">.</span><span class="n">STATUS_UNKNOWN_CAMERA</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&quot;Camera source &#39;</span><span class="si">%s</span><span class="s2">&#39; is unknown.&quot;</span><span class="p">,</span> <span class="n">src_name</span><span class="p">)</span>
                    <span class="k">continue</span>

                <span class="k">if</span> <span class="n">img_req</span><span class="o">.</span><span class="n">resize_ratio</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">img_req</span><span class="o">.</span><span class="n">resize_ratio</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
                    <span class="n">img_resp</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">ImageResponse</span><span class="o">.</span><span class="n">STATUS_UNSUPPORTED_RESIZE_RATIO_REQUESTED</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&quot;Resize ratio </span><span class="si">%f</span><span class="s2"> is unsupported.&quot;</span><span class="p">,</span> <span class="n">img_req</span><span class="o">.</span><span class="n">resize_ratio</span><span class="p">)</span>
                    <span class="k">continue</span>

                <span class="k">if</span> <span class="n">img_req</span><span class="o">.</span><span class="n">HasField</span><span class="p">(</span><span class="s2">&quot;custom_params&quot;</span><span class="p">):</span>
                    <span class="n">value_validation_error</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">image_sources_mapped</span><span class="p">[</span><span class="n">src_name</span><span class="p">]</span><span class="o">.</span><span class="n">value_validator</span><span class="p">(</span>
                        <span class="n">img_req</span><span class="o">.</span><span class="n">custom_params</span><span class="p">)</span>
                    <span class="k">if</span> <span class="n">value_validation_error</span><span class="p">:</span>
                        <span class="n">img_resp</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">ImageResponse</span><span class="o">.</span><span class="n">STATUS_CUSTOM_PARAMS_ERROR</span>
                        <span class="n">img_resp</span><span class="o">.</span><span class="n">custom_param_error</span><span class="o">.</span><span class="n">CopyFrom</span><span class="p">(</span><span class="n">value_validation_error</span><span class="p">)</span>
                        <span class="k">continue</span>

                <span class="c1"># Set the image source information in the response.</span>
                <span class="n">img_resp</span><span class="o">.</span><span class="n">source</span><span class="o">.</span><span class="n">CopyFrom</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">image_sources_mapped</span><span class="p">[</span><span class="n">src_name</span><span class="p">]</span><span class="o">.</span><span class="n">image_source_proto</span><span class="p">)</span>

                <span class="c1"># Set the image capture parameters in the response.</span>
                <span class="n">img_resp</span><span class="o">.</span><span class="n">shot</span><span class="o">.</span><span class="n">capture_params</span><span class="o">.</span><span class="n">CopyFrom</span><span class="p">(</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">image_sources_mapped</span><span class="p">[</span><span class="n">src_name</span><span class="p">]</span><span class="o">.</span><span class="n">get_image_capture_params</span><span class="p">(</span>
                        <span class="n">img_req</span><span class="o">.</span><span class="n">custom_params</span><span class="p">))</span>

                <span class="k">if</span> <span class="n">img_req</span><span class="o">.</span><span class="n">HasField</span><span class="p">(</span><span class="s2">&quot;custom_params&quot;</span><span class="p">):</span>
                    <span class="c1">#If future keyword arguments are added here, they&#39;ll need to be added to this call</span>
                    <span class="c1">#get_image_and_timestamp already calls a &#39;sanitized&#39; capture function that handles pre-3.3 blocking_captures</span>
                    <span class="n">captured_image</span><span class="p">,</span> <span class="n">img_time_seconds</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">image_sources_mapped</span><span class="p">[</span>
                        <span class="n">src_name</span><span class="p">]</span><span class="o">.</span><span class="n">get_image_and_timestamp</span><span class="p">(</span><span class="n">custom_params</span><span class="o">=</span><span class="n">img_req</span><span class="o">.</span><span class="n">custom_params</span><span class="p">)</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="c1">#get_image_and_timestamp() can accommodate pre-3.3 blocking_capture calls if no custom params are supplied</span>
                    <span class="n">captured_image</span><span class="p">,</span> <span class="n">img_time_seconds</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">image_sources_mapped</span><span class="p">[</span>
                        <span class="n">src_name</span><span class="p">]</span><span class="o">.</span><span class="n">get_image_and_timestamp</span><span class="p">()</span>

                <span class="k">if</span> <span class="n">captured_image</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">or</span> <span class="n">img_time_seconds</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                    <span class="n">img_resp</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">ImageResponse</span><span class="o">.</span><span class="n">STATUS_IMAGE_DATA_ERROR</span>
                    <span class="n">error_message</span> <span class="o">=</span> <span class="s2">&quot;Failed to capture an image from </span><span class="si">%s</span><span class="s2"> on the server.&quot;</span> <span class="o">%</span> <span class="n">src_name</span>
                    <span class="n">response</span><span class="o">.</span><span class="n">header</span><span class="o">.</span><span class="n">error</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">error_message</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="n">error_message</span><span class="p">)</span>
                    <span class="k">continue</span>

                <span class="c1"># Convert the image capture time from the local clock time into the robot&#39;s time. Then set it as</span>
                <span class="c1"># the acquisition timestamp for the image data.</span>
                <span class="n">img_resp</span><span class="o">.</span><span class="n">shot</span><span class="o">.</span><span class="n">acquisition_time</span><span class="o">.</span><span class="n">CopyFrom</span><span class="p">(</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">bosdyn_sdk_robot</span><span class="o">.</span><span class="n">time_sync</span><span class="o">.</span><span class="n">robot_timestamp_from_local_secs</span><span class="p">(</span>
                        <span class="n">img_time_seconds</span><span class="p">))</span>

                <span class="n">img_resp</span><span class="o">.</span><span class="n">shot</span><span class="o">.</span><span class="n">image</span><span class="o">.</span><span class="n">rows</span> <span class="o">=</span> <span class="n">img_resp</span><span class="o">.</span><span class="n">source</span><span class="o">.</span><span class="n">rows</span>
                <span class="n">img_resp</span><span class="o">.</span><span class="n">shot</span><span class="o">.</span><span class="n">image</span><span class="o">.</span><span class="n">cols</span> <span class="o">=</span> <span class="n">img_resp</span><span class="o">.</span><span class="n">source</span><span class="o">.</span><span class="n">cols</span>

                <span class="c1"># Set the image data.</span>
                <span class="n">img_resp</span><span class="o">.</span><span class="n">shot</span><span class="o">.</span><span class="n">image</span><span class="o">.</span><span class="n">format</span> <span class="o">=</span> <span class="n">img_req</span><span class="o">.</span><span class="n">image_format</span>
                <span class="n">decode_status</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_set_format_and_decode</span><span class="p">(</span><span class="n">captured_image</span><span class="p">,</span> <span class="n">img_resp</span><span class="o">.</span><span class="n">shot</span><span class="o">.</span><span class="n">image</span><span class="p">,</span>
                                                            <span class="n">img_req</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">decode_status</span> <span class="o">!=</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">ImageResponse</span><span class="o">.</span><span class="n">STATUS_OK</span><span class="p">:</span>
                    <span class="n">img_resp</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="n">decode_status</span>

                <span class="c1"># Set that we successfully got the image.</span>
                <span class="k">if</span> <span class="n">img_resp</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">ImageResponse</span><span class="o">.</span><span class="n">STATUS_UNKNOWN</span><span class="p">:</span>
                    <span class="n">img_resp</span><span class="o">.</span><span class="n">status</span> <span class="o">=</span> <span class="n">image_pb2</span><span class="o">.</span><span class="n">ImageResponse</span><span class="o">.</span><span class="n">STATUS_OK</span>

            <span class="c1"># No header error codes, so set the response header as CODE_OK.</span>
            <span class="n">populate_response_header</span><span class="p">(</span><span class="n">response</span><span class="p">,</span> <span class="n">request</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">response</span></div>

    <span class="k">def</span> <span class="fm">__del__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">source</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">image_sources_mapped</span><span class="o">.</span><span class="n">values</span><span class="p">():</span>
            <span class="n">source</span><span class="o">.</span><span class="n">stop_capturing</span><span class="p">()</span></div>
</pre></div>

           </div>
          </div>
          <footer>
  

  <hr/>

  <div role="contentinfo">
    <p>
      
      &copy; Copyright 2025 Boston Dynamics. All rights reserved.
      <a href="https://www.bostondynamics.com/privacy-policy">Privacy Policy</a> | 
      <a href="https://www.bostondynamics.com/terms">Terms of Use</a>

    </p>
  </div> 

</footer>
        </div>
      </div>
    </section>
  </div>
  <script>
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(false);
      });
  </script>
    <!-- Theme Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXXX-1"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());

      gtag('config', 'UA-XXXXXXX-1', {
          'anonymize_ip': false,
      });
    </script> 

</body>
</html>